package cn.kgc.config;

import cn.kgc.service.SenderMessageInfoService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.rabbit.connection.ConnectionFactory;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.amqp.support.converter.Jackson2JsonMessageConverter;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import javax.annotation.Resource;

/**
 * @author wangyue
 * @version 1.0
 */
@Slf4j
@Configuration
@SuppressWarnings("all")
public class RabbitSenderConfig {

    @Resource
    private SenderMessageInfoService sendMessageInfoService;

    @Value("${mq.serviceName}")
    private String serviceName;

    @Bean
    public RabbitTemplate rabbitTemplate(ConnectionFactory connectionFactory){
        RabbitTemplate rabbitTemplate=new RabbitTemplate();
        rabbitTemplate.setConnectionFactory(connectionFactory);
        rabbitTemplate.setMessageConverter(new Jackson2JsonMessageConverter());
        //确认消息是否进入到交换机中
        rabbitTemplate.setConfirmCallback((correlationData, b, s) -> {
            if(b){
                log.debug("消息成功进入交换机,从数据库中删除消息。消息的id是:{}",correlationData.getId());
                String id = correlationData.getId();
                sendMessageInfoService.messageSendSuccess(id);
            }else{
                log.debug("消息进入交换机失败，消息的id是:{}",correlationData.getId());
            }
        });
        rabbitTemplate.setMandatory(true);
        //如果是延迟消息不需要判断消息是否进入到队列中。
        //因为延迟消息不会立即进入到消息队列中,而我们的setReturnCallback方法 会立即判断消息是否进入到队列中。
        rabbitTemplate.setReturnCallback((message, replyCode, replyText, exchange, routingKey) -> {
            int delay=(int) message.getMessageProperties().getHeaders().get("delay");
            if(delay<=0) { //如果不是延迟消息判断消息是否进入到队列中。
                log.debug("消息没有进入队列，将消息重新放入到数据库中,消息是:{}", message);
                //从消息头中获得消息已经被发送的次数
                int sequence = (Integer) (message.getMessageProperties().getHeaders().get("sequence"));
                //获得发送消息的内容
                String jsonString = new String(message.getBody());
                //将消息保存到数据库中
                sendMessageInfoService.messageSendReturn(
                        exchange, routingKey, jsonString, sequence, serviceName, delay
                );
            }
        });
        return rabbitTemplate;
    }
}